package com.tjakus.crypto;

import javax.crypto.*;
import javax.crypto.spec.*;
import org.apache.commons.codec.binary.Base64;

/**
 * Class which provides methods for encrypting and decrypting strings using a
 * DES encryption algorithm. Strings can be encrypted and then are returned
 * translated into a Base64 Ascii String.
 * 
 * @author tjakus
 * 
 */

public class CryptoManager {

	private static Cipher encryptCipher = null;
	private static Cipher decryptCipher = null;

	/**
	 * Initialize a new object which can be utilized to encrypt and decrypt
	 * strings using the specified key with a DES encryption algorithm.
	 */
	public static void initializeCryptoManager() throws Exception {
		// Generate the secret key
		String secretKeyString = "aAbBcCdD12345678";
		DESKeySpec key = new DESKeySpec(secretKeyString.getBytes());
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey secretKey = keyFactory.generateSecret(key);
		encryptCipher = Cipher.getInstance("DES");
		decryptCipher = Cipher.getInstance("DES");
		encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey);
		decryptCipher.init(Cipher.DECRYPT_MODE, secretKey);
	}

	/**
	 * Encrypt a string using DES encryption, and return the encrypted string as
	 * a base64 encoded string.
	 */
	public static String encryptBase64(String unencryptedString)
			throws Exception {
		// Encode the string into bytes using utf-8
		byte[] unencryptedByteArray = unencryptedString.getBytes("UTF8");

		// Encrypt
		byte[] encryptedBytes = encryptCipher.doFinal(unencryptedByteArray);

		// Encode bytes to base64 to get a string
		byte[] encodedBytes = Base64.encodeBase64(encryptedBytes);

		return new String(encodedBytes);
	}

	/**
	 * Decrypt a base64 encoded, DES encrypted string and return the unencrypted
	 * string.
	 */
	public static String decryptBase64(String encryptedString) throws Exception {
		// Encode bytes to base64 to get a string
		byte[] decodedBytes = Base64.decodeBase64(encryptedString.getBytes());

		// Decrypt
		byte[] unencryptedByteArray = decryptCipher.doFinal(decodedBytes);

		// Decode using utf-8
		return new String(unencryptedByteArray, "UTF8");
	}
}